Goal: Build an interface to configure your experiment's parameters (like trial count and timing) and connect them to your code.
This step teaches you to systematically configure your psychology experiment's timing, structure, and conditions. You'll learn to balance statistical power with participant engagement while following psychology research best practices.
What You'll Learn:
This interface allows you to change the parameters for our Rock-Paper-Scissors example. The settings you save here will be used in the next step. Test how different configurations change the feel of the experiment.
With your current settings, this experiment will take approximately: ~1 minute
This helps you plan reasonable experiment lengths for your participants.
For your own research, a structured text file is the professional standard for managing experiment parameters. Below, we'll guide you through creating a config.json file for your experiment from Step 0.
A JSON (JavaScript Object Notation) file is a simple, human-readable format for storing structured dataβthink of it as a digital recipe card for your experiment.
Use the following prompt with an AI assistant to create a starting config.json file. Make sure to provide the AI with the context of your research question and methodology from Step 0.
Based on the research study I've provided from Step 0, create a `config.json` file for my experiment. The file should include parameters for:
Keep the JSON clean and well-structured.
After running the prompt, save the output into a new file named config.json in your project folder. We'll use this file in the next part.
Now, provide the AI with your newly created config.json file and ask it to write the core logic for your experiment.
Using the provided `config.json`, write the JavaScript logic for my experiment. This should include:
Your generated file will look something like this, but tailored to your specific study. For a more detailed example, see the RPS experiment's configuration.
{
"experiment": {
"title": "My Reaction Time Study",
"version": "1.0"
},
"timing": {
"feedbackDuration": 1000
},
"structure": {
"experimentTrials": 50
}
}
With a config.json file (or the RPS settings you saved to localStorage) in place, your experiment needs to load and apply those values at runtime. Here's a concise pattern you can adapt:
// Load configuration at experiment startup
async function loadConfig() {
try {
const response = await fetch('config.json');
const config = await response.json();
// Apply timing settings
experimentParams.trialDuration = config.timing.trialDuration;
experimentParams.interTrialInterval = config.timing.interTrialInterval;
// Apply structure settings
experimentParams.totalTrials = config.structure.experimentTrials;
experimentParams.practiceTrials = config.structure.practiceTrials;
console.log('Configuration loaded:', config);
} catch (error) {
console.error('Failed to load config, using defaults:', error);
}
}
// Use configuration to control experiment flow
function startTrial() {
// Use configured timing
setTimeout(() => {
hideStimulusAndCollectResponse();
}, config.timing.trialDuration);
}
function endTrial() {
// Use configured inter-trial interval
setTimeout(() => {
if (config.display?.showProgress) {
updateProgressBar();
}
startNextTrial();
}, config.timing.interTrialInterval);
}
In Step 6, your experiment will generate a single JSON file for each participant, ready for analysis. This file should combine participant details, the session's configuration, and the trial-by-trial data.
Here is the recommended structure, which you will build toward in the next step. It has three top-level keys:
participant β The name and (optional) age the participant entered before starting the task.configuration β The full experiment configuration that was active for this session (from Step 5).trialData β An array of records for each trial, produced by your experiment logic.{
"participant": {
"name": "Alice",
"age": 29
},
"configuration": {
"numTrials": 30,
"showProgress": true,
"aiAlgorithm": "counter"
},
"trialData": [
{ "round": 1, "playerChoice": "Rock", "aiChoice": "Paper", "outcome": "loss" },
{ "round": 2, "playerChoice": "Paper", "aiChoice": "Scissors", "outcome": "loss" }
// β¦ additional trials β¦
]
}
Your trialData objects can include any additional fields you log (e.g., reaction time, confidence ratings). Just make sure each trial is an object in this array.
In the next step, you will use a function like this to assemble and download the final results object:
// Build the results package at the end of the experiment
function buildResultsPackage(config, trials, participant) {
return {
participant, // e.g., { name: 'Alice', age: 29 }
configuration: config,
trialData: trials
};
}
// This function will be called from your "Download Results" button
function exportResults() {
const participantInfo = {
name: gameState.participantName,
age: gameState.participantAge
};
const resultsPackage = buildResultsPackage(gameConfig, gameState.trialData, participantInfo);
// Helper to trigger browser download
downloadJSON(resultsPackage, `results_${participantInfo.name || 'participant'}.json`);
}
With this structure defined, you are ready to build the interactive logic in Step 6 that will generate these files.